package com.线程Thread.线程同步;

@SuppressWarnings("all")
public class 线程死锁 {
    public static void main(String[] args) {
        /**基本介绍
         * 1.多个线程都占用了对方的锁资源，但不肯相让，导致了死锁；
         * 举个栗子：
         * 妈妈：你先完成作业，才让你玩手机；
         * 儿子：那先让我玩手机，我才写作业；
         */
        MyThread m1 = new MyThread(true);///执行第一个分支
        m1.setName("m1");
        MyThread m2 = new MyThread(false);///执行第二个分支
        m2.setName("m2");
        m1.start();
        m2.start();
    }
}

class MyThread extends Thread {
    static Object a = new Object();  ///所有对象共用一个a，保证锁的唯一，多个线程都会抢一个锁；
    static Object b = new Object();
    boolean flag;   ///控制分支的走向；

    public MyThread(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        /// 如果b锁被m2抢走了，释放之前m1抢不到b，又因为a被m1抢走了，m2也抢不到a锁  ===  死锁；
        if (flag) {
            synchronized (a) {
                System.out.println(Thread.currentThread().getName() + "进入了1");
                synchronized (b) {
                    System.out.println(Thread.currentThread().getName() + "进入了2");
                }
            }
        }
        else
            synchronized (b) {
                System.out.println(Thread.currentThread().getName() + "进入了3");
                synchronized (a) {
                    System.out.println(Thread.currentThread().getName() + "进入了4");
                }
            }
    }


}
/***  a，b是static共享的；
 * 1. m1启动线程后抢到了a锁，同时m2抢到了b锁
 * 2.1  m1运行到这里时，因为b锁在m2手中，得先让m2释放锁m1才能拿到b锁
 *      synchronized (b) {
 *        System.out.println(Thread.currentThread().getName() + "进入了2");}
 * 2.2 同时  m2运行到这里时，因为a锁在m1手中，得先让m1释放锁m2才能拿到a锁
 *          synchronized (a) {
 *              System.out.println(Thread.currentThread().getName() + "进入了4");}
 * 3.各自都想下一步，但需要的锁在对方，导致死锁；
 */